package com.bob;


import com.bob.common.DataStore;
import com.bob.common.GitPatchGenerator;
import com.bob.common.GitRepository;
import com.bob.common.PomReader;
import com.bob.common.bean.ResourcesRef;
import com.bob.common.resources.ResourcesExec;
import com.bob.common.resources.exec.DefaultExec;
import com.bob.common.utils.FileUtil;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.logging.SystemStreamLog;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;


/**
 * 增量升级
 *
 * @author heh
 */
@Mojo( name = "upgrade",defaultPhase = LifecyclePhase.PACKAGE,threadSafe=true)
@Execute(phase = LifecyclePhase.PACKAGE,goal="upgrade")
public class UpgradeMojo extends AbstractMojo {
    private static Log logger = new SystemStreamLog();

    /**
     * Git版本号：SHA-1全称，或简称
     */
    @Parameter(property = "gitVersions" ,defaultValue = "HEAD")
    private String [] gitVersions;

    /**
     * 增量包的输出路径
     */
    @Parameter(property = "patchOutPath",required = true ,defaultValue ="${session.executionRootDirectory}\\patchOut\\")
    private File patchOutPath;

    /**
     *  项目根目录
     */
    @Parameter(property = "session.executionRootDirectory" ,defaultValue = "session.executionRootDirectory")
    private File rootDir;
    /**
     * 项目目录
     */
    @Parameter(property = "project.basedir" ,defaultValue = "project.basedir")
    private File baseDir;


    /**
     * Location of the file.
     *
     */
    @Parameter(property = "project.build.directory" ,defaultValue = "project.build.directory")
    private File outputDirectory;

    /**
     * Location of the file.
     *
     */
    @Parameter(property = "project.build.outputDirectory" ,defaultValue = "project.build.outputDirectory")
    private File classOutputDirectory;

    /**
     * 源文件路径.
     *
     */
    @Parameter(property = "project.build.sourceDirectory" ,defaultValue = "project.build.sourceDirectory")
    private File sourceDirectory;

    /**
     * 测试源文件路径.
     *
     */
    @Parameter(property = "project.build.testSourceDirectory" ,defaultValue = "project.build.testSourceDirectory")
    private File testSourceDirectory;

    /**
     * 脚本文件路径.
     */
    @Parameter(property = "project.build.scriptSourceDirectory" ,defaultValue = "project.build.scriptSourceDirectory")
    private File scriptSourceDirectory;

    /**
     * 资源文件路径.
     *
     */
    /*@Parameter(property = "project.build.resources" ,defaultValue = "project.build.resources")
    private Resource[] mainResources;
*/

    /**
     * 测试源文件路径.
     */
    /*@Parameter(property = "project.build.testResources" ,defaultValue = "project.build.testResources")
    private Resource[] testResources;*/

    /**
     * 最终名称
     *
     */
    @Parameter(property = "project.build.finalName" ,defaultValue = "project.build.finalName")
    private String finalName;

    /**
     * 打包方式
     */
    @Parameter(property = "project.packaging" ,defaultValue = "project.packaging")
    private String packaging;


    /**
     * 自定义资源文件映射
     */
    @Parameter(property = "resourcesRef" ,required = false)
    private List<ResourcesRef> resourcesRefs = new ArrayList<>();

    @Override
    public void execute()  {
        logger.info(String.format("=================gitVersions %s==========================" , Arrays.asList(gitVersions)) );
        logger.info(String.format("=================rootDir %s==========================" , rootDir.getAbsolutePath()) );
        logger.info(String.format("=================basedir %s==========================" , baseDir.getAbsolutePath() ));
        logger.info(String.format("=================outputDirectory %s==========================" , outputDirectory.getAbsolutePath() ));
        logger.info(String.format("=================classOutputDirectory %s==========================" , classOutputDirectory.getAbsolutePath() ));
        logger.info(String.format("=================sourceDirectory %s==========================" , sourceDirectory.getAbsolutePath() ));
        logger.info(String.format("=================testSourceDirectory %s==========================" , testSourceDirectory.getAbsolutePath() ));
        logger.info(String.format("=================scriptSourceDirectory %s==========================" , scriptSourceDirectory.getAbsolutePath() ));
        /*logger.info(String.format("=================mainResources %s==========================" , Arrays.stream(mainResources).map(Resource::toString).collect(Collectors.joining(","))));
        logger.info(String.format("=================testResources %s==========================" , Arrays.stream(testResources).map(Resource::toString).collect(Collectors.joining(","))));
       */
        logger.info(String.format("=================finalName %s==========================" , finalName ));
        logger.info(String.format("=================packaging %s==========================" , packaging ));
        logger.info(String.format("=================patchOutPatchPath %s==========================" , patchOutPath));

        File patchPath = GitPatchGenerator.initPatchOutPath(this.patchOutPath);

        // 只需要根目录执行一次即可
        if(rootDir.equals(baseDir)){
            // 设置项目根目录
            DataStore.getDataStore().setRootDir(this.rootDir.getAbsolutePath());
            // 初始化文件映射
            ResourcesExec resourcesExec = new DefaultExec();
            resourcesExec.initResources(resourcesRefs);
            // 解析 pom 依赖关系
            FutureTask<Boolean> pomReaderTask = new FutureTask((Callable<Boolean>) () -> {
                new PomReader().initPomDataStore(rootDir.getAbsolutePath());
                return true;
            });
            new Thread(pomReaderTask).start();
            // 初始化git
            FutureTask<Boolean> gitRepositoryTask = new FutureTask((Callable<Boolean>) () -> {
                try {
                    GitRepository gitRepository = new GitRepository(this.rootDir.getAbsolutePath());
                    //  根据 commitId 查找git log
                    gitRepository.scanLog(this.gitVersions);
                    // project diff 文件清单
                    gitRepository.getDiffItems();
                } catch (IOException | org.eclipse.jgit.api.errors.GitAPIException  e) {
                    e.printStackTrace();
                }finally {
                    GitPatchGenerator.writeChangeLogToPatchFile(patchPath);
                }
                return true;
            });
            new Thread(gitRepositoryTask).start();
            try {
                pomReaderTask.get();
                gitRepositoryTask.get();
            } catch (InterruptedException|ExecutionException e) {
                e.printStackTrace();
            }
        }

        GitPatchGenerator.copyFileToPatchDir(this.baseDir,this.outputDirectory,patchPath,this.finalName,this.packaging);

        // 打开补丁文件夹
        FileUtil.openFolder(patchPath);

    }



}
